View Javadoc

1   /**
2    * Copyright 2008 WebPhotos
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sf.webphotos.netbeans.project.empty;
17  
18  import java.awt.Component;
19  import java.io.ByteArrayInputStream;
20  import java.io.ByteArrayOutputStream;
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.text.MessageFormat;
26  import java.util.Enumeration;
27  import java.util.LinkedHashSet;
28  import java.util.NoSuchElementException;
29  import java.util.Set;
30  import java.util.zip.ZipEntry;
31  import java.util.zip.ZipInputStream;
32  import javax.swing.JComponent;
33  import javax.swing.event.ChangeListener;
34  import net.sf.webphotos.netbeans.project.Constants.ProjectFactory.EmptyProject;
35  import org.netbeans.api.project.ProjectManager;
36  import org.netbeans.api.templates.TemplateRegistration;
37  import org.netbeans.spi.project.ui.support.ProjectChooser;
38  import org.netbeans.spi.project.ui.templates.support.Templates;
39  import org.openide.WizardDescriptor;
40  import org.openide.filesystems.FileObject;
41  import org.openide.filesystems.FileUtil;
42  import org.openide.util.Exceptions;
43  import org.openide.util.NbBundle;
44  import org.openide.xml.XMLUtil;
45  import org.w3c.dom.Document;
46  import org.w3c.dom.Element;
47  import org.w3c.dom.NodeList;
48  import org.xml.sax.InputSource;
49  
50  public class EmptyWebPhotosProjectWizardIterator implements WizardDescriptor.InstantiatingIterator {
51      public static final String PROP_PROJECT_DIR = "projdir";
52      public static final String PROP_PROJECT_NAME = "name";
53  
54      private int index;
55      private WizardDescriptor.Panel[] panels;
56      private WizardDescriptor wiz;
57  
58      public EmptyWebPhotosProjectWizardIterator() {
59      }
60  
61      @TemplateRegistration(
62              folder = EmptyProject.PROJECT_FOLDER, 
63              displayName = EmptyProject.PROJECT_DISPLAY_MANE, 
64              iconBase = EmptyProject.PROJECT_ICON_BASE, 
65              description = EmptyProject.PROJECT_DESCRIPTION)
66      public static EmptyWebPhotosProjectWizardIterator createIterator() {
67          return new EmptyWebPhotosProjectWizardIterator();
68      }
69  
70      private WizardDescriptor.Panel[] createPanels() {
71          return new WizardDescriptor.Panel[]{
72                      new EmptyWebPhotosProjectWizardPanel(),};
73      }
74  
75      private String[] createSteps() {
76          return new String[]{
77                      NbBundle.getMessage(EmptyWebPhotosProjectWizardIterator.class, "LBL_CreateProjectStep")
78                  };
79      }
80  
81      @Override
82      public Set<FileObject> instantiate() throws IOException {
83          Set<FileObject> resultSet = new LinkedHashSet<FileObject>();
84          File dirF = FileUtil.normalizeFile((File) wiz.getProperty(PROP_PROJECT_DIR));
85          dirF.mkdirs();
86  
87          FileObject template = Templates.getTemplate(wiz);
88          FileObject dir = FileUtil.toFileObject(dirF);
89          unZipFile(template.getInputStream(), dir);
90  
91          // Always open top dir as a project:
92          resultSet.add(dir);
93          // Look for nested projects to open as well:
94          Enumeration<? extends FileObject> e = dir.getFolders(true);
95          while (e.hasMoreElements()) {
96              FileObject subfolder = e.nextElement();
97              if (ProjectManager.getDefault().isProject(subfolder)) {
98                  resultSet.add(subfolder);
99              }
100         }
101 
102         File parent = dirF.getParentFile();
103         if (parent != null && parent.exists()) {
104             ProjectChooser.setProjectsFolder(parent);
105         }
106 
107         return resultSet;
108     }
109 
110     @Override
111     public void initialize(WizardDescriptor wiz) {
112         this.wiz = wiz;
113         index = 0;
114         panels = createPanels();
115         // Make sure list of steps is accurate.
116         String[] steps = createSteps();
117         for (int i = 0; i < panels.length; i++) {
118             Component c = panels[i].getComponent();
119             if (steps[i] == null) {
120                 // Default step name to component name of panel.
121                 // Mainly useful for getting the name of the target
122                 // chooser to appear in the list of steps.
123                 steps[i] = c.getName();
124             }
125             if (c instanceof JComponent) { // assume Swing components
126                 JComponent jc = (JComponent) c;
127                 // Step #.
128                 jc.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, new Integer(i));
129                 // Step name (actually the whole list for reference).
130                 jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, steps);
131             }
132         }
133     }
134 
135     @Override
136     public void uninitialize(WizardDescriptor wiz) {
137         this.wiz.putProperty(PROP_PROJECT_DIR, null);
138         this.wiz.putProperty(PROP_PROJECT_NAME, null);
139         this.wiz = null;
140         panels = null;
141     }
142 
143     @Override
144     public String name() {
145         return MessageFormat.format("{0} of {1}",
146                 new Object[]{new Integer(index + 1), new Integer(panels.length)});
147     }
148 
149     @Override
150     public boolean hasNext() {
151         return index < panels.length - 1;
152     }
153 
154     @Override
155     public boolean hasPrevious() {
156         return index > 0;
157     }
158 
159     @Override
160     public void nextPanel() {
161         if (!hasNext()) {
162             throw new NoSuchElementException();
163         }
164         index++;
165     }
166 
167     @Override
168     public void previousPanel() {
169         if (!hasPrevious()) {
170             throw new NoSuchElementException();
171         }
172         index--;
173     }
174 
175     @Override
176     public WizardDescriptor.Panel current() {
177         return panels[index];
178     }
179 
180     // If nothing unusual changes in the middle of the wizard, simply:
181     @Override
182     public final void addChangeListener(ChangeListener l) {
183     }
184 
185     @Override
186     public final void removeChangeListener(ChangeListener l) {
187     }
188 
189     private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException {
190         try {
191             ZipInputStream str = new ZipInputStream(source);
192             ZipEntry entry;
193             while ((entry = str.getNextEntry()) != null) {
194                 if (entry.isDirectory()) {
195                     FileUtil.createFolder(projectRoot, entry.getName());
196                 } else {
197                     FileObject fo = FileUtil.createData(projectRoot, entry.getName());
198                     if ("nbproject/project.xml".equals(entry.getName())) {
199                         // Special handling for setting name of Ant-based projects; customize as needed:
200                         filterProjectXML(fo, str, projectRoot.getName());
201                     } else {
202                         writeFile(str, fo);
203                     }
204                 }
205             }
206         } finally {
207             source.close();
208         }
209     }
210 
211     private static void writeFile(ZipInputStream str, FileObject fo) throws IOException {
212         OutputStream out = fo.getOutputStream();
213         try {
214             FileUtil.copy(str, out);
215         } finally {
216             out.close();
217         }
218     }
219 
220     private static void filterProjectXML(FileObject fo, ZipInputStream str, String name) throws IOException {
221         try {
222             ByteArrayOutputStream baos = new ByteArrayOutputStream();
223             FileUtil.copy(str, baos);
224             Document doc = XMLUtil.parse(new InputSource(new ByteArrayInputStream(baos.toByteArray())), false, false, null, null);
225             NodeList nl = doc.getDocumentElement().getElementsByTagName(PROP_PROJECT_NAME);
226             if (nl != null) {
227                 for (int i = 0; i < nl.getLength(); i++) {
228                     Element el = (Element) nl.item(i);
229                     if (el.getParentNode() != null && "data".equals(el.getParentNode().getNodeName())) {
230                         NodeList nl2 = el.getChildNodes();
231                         if (nl2.getLength() > 0) {
232                             nl2.item(0).setNodeValue(name);
233                         }
234                         break;
235                     }
236                 }
237             }
238             OutputStream out = fo.getOutputStream();
239             try {
240                 XMLUtil.write(doc, out, "UTF-8");
241             } finally {
242                 out.close();
243             }
244         } catch (Exception ex) {
245             Exceptions.printStackTrace(ex);
246             writeFile(str, fo);
247         }
248 
249     }
250 }